package org.example.interceptor;

import cn.hutool.core.util.StrUtil;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Map;
import java.util.Properties;

/**
 * @author 韦兵
 * @since 2025/7/5 16:46
 */
@Intercepts({
        @Signature(
                type = ParameterHandler.class,
                method = "setParameters",
                args = {PreparedStatement.class}
        ),
        @Signature(
                type = StatementHandler.class,
                method = "prepare",
                args = {Connection.class, Integer.class}
        ),
        @Signature(
                type = ResultSetHandler.class,
                method = "handleResultSets",
                args = {Statement.class}
        )
    }
)
public class TestInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        // 拦截逻辑
        Object target = invocation.getTarget();
        System.out.println("拦截了一下下----------------------------拦截到了:" + target.getClass());

        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        // 测试1:拦截我声明的需要拦截的3个中的2个:确实拦截了
        /*if (target instanceof ParameterHandler || target instanceof StatementHandler) {
            return Plugin.wrap(target, this);
        } else {
            return target;
        }*/

        // 测试2:拦截一个我没声明需要拦截的:没走拦截逻辑
        /*if (target instanceof Executor) {
            return Plugin.wrap(target, this);
        } else {
            return target;
        }*/

        // 测试3:这里我只写return target;更是一个都没拦截到
//        return target;

        // 测试4:只写return Plugin.wrap(target, this);
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        // 输出一下读取到的参数
        String format = "key:{},value:{}";
        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
            String pair = StrUtil.format(format, entry.getKey(), entry.getValue());
            System.out.println(pair);
        }
    }
}
